package com.eorchis.module.basedata.service.impl;

import com.eorchis.module.basedata.domain.BaseData;
import com.eorchis.module.basedata.domain.BaseDataCondition;
import com.eorchis.module.basedata.domain.BaseDataType;
import com.eorchis.module.basedata.domain.BaseDataTypeCondition;
import com.eorchis.module.basedata.service.IBaseDataService;
import com.eorchis.module.basedata.service.IBaseDataTypeService;
import com.eorchis.module.basedata.service.cache.BaseDataCacheUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import org.springframework.context.ApplicationContext;

public class BaseDataUtil
  implements Cloneable
{
  private static ApplicationContext ac = null;
  private IBaseDataService baseDataService = null;
  private IBaseDataTypeService baseDataTypeService = null;
  private static ServletContext servletContext;
  public static final String BASE_DATA_MAP = "ORCHID_BASE_DATA_MAP";
  public static final String BASE_DATA_TYPE_MAP = "ORCHID_BASE_DATA_TYPE_MAP";
  public static final String BASE_DATA_TYPE_ID_TO_CODE = "ORCHID_BASE_DATA_TYPE_ID_TO_CODE";
  private static BaseDataCacheUtil baseDataCacheUtil;

  public BaseDataUtil(ApplicationContext pplicationContext, ServletContext sc)
  {
    this.ac = pplicationContext;
    servletContext = sc;
  }

  public Map<String, BaseData> init()
  {
    baseDataCacheUtil = (BaseDataCacheUtil)ac.getBean("com.eorchis.module.basedata.service.cache.BaseDataCacheUtil");

    Map initBaseData = baseDataCacheUtil.initBaseData();
    servletContext.setAttribute("baseDataMap", initBaseData);
    return initBaseData;
  }

  public static void update(BaseData baseData)
    throws Exception
  {
    Map dbMapClone = (Map)((HashMap)servletContext.getAttribute("baseDataMap")).clone();

    baseDataCacheUtil = (BaseDataCacheUtil)ac.getBean("com.eorchis.module.basedata.service.cache.BaseDataCacheUtil");

    baseDataCacheUtil.putBaseData(dbMapClone);

    servletContext.setAttribute("baseDataMap", dbMapClone);
    Map baseDataTypes = baseDataCacheUtil.getBaseDataList();

    Map baseDataTypeIdToCodes = baseDataCacheUtil.getBaseDataTypeIdToTypeCodes();

    String dataTypeCode = null;
    if ((baseData.getBaseDataType() != null) && (!"".equals(baseData.getBaseDataType())))
    {
      IBaseDataTypeService baseDataTypeService = (IBaseDataTypeService)ac.getBean("com.eorchis.module.basedata.service.impl.BaseDataTypeServiceImpl");
      BaseDataTypeCondition condition = new BaseDataTypeCondition();
      condition.setSearchTypeID(baseData.getBaseDataType().getTypeID());
      BaseDataType baseDataType = baseDataTypeService.getBaseDataType(condition);
      baseData.setBaseDataType(baseDataType);
      if (baseDataTypeIdToCodes.containsKey(baseData.getBaseDataType().getTypeID()))
      {
        dataTypeCode = (String)baseDataTypeIdToCodes.get(baseData.getBaseDataType().getTypeID());
      }

      List baseDatas = null;
      if ((dataTypeCode != null) && (!"".equals(dataTypeCode))) {
        baseDatas = (List)baseDataTypes.get(dataTypeCode);
        if ((baseDatas == null) || ("".equals(baseDatas))) {
          baseDatas = new ArrayList();
        }
        Iterator ite = baseDatas.iterator();
        while (ite.hasNext()) {
          BaseData bData = (BaseData)ite.next();
          if (bData.getDataCode().equalsIgnoreCase(baseData.getDataCode())) {
            ite.remove();
            break;
          }
        }
        if (baseData.getActiveState().intValue() == BaseData.IS_ACTIVE_Y.intValue())
        {
          baseDatas.add(baseData);
          baseData.getBaseDataType().setTypeCode(dataTypeCode);
          dbMapClone.put(baseData.getDataCode(), baseData);
        }
        baseDataTypes.put(dataTypeCode, baseDatas);
        baseDataCacheUtil.putBaseDataList(baseDataTypes);
      }
    }
  }

  public static void delete(String[] dataCodes)
    throws Exception
  {
    baseDataCacheUtil = (BaseDataCacheUtil)ac.getBean("com.eorchis.module.basedata.service.cache.BaseDataCacheUtil");

    Map dbMapClone = (Map)((HashMap)servletContext.getAttribute("baseDataMap")).clone();

    Map baseDataTypes = baseDataCacheUtil.getBaseDataList();

    Map baseDataTypeIdToCodes = baseDataCacheUtil.getBaseDataTypeIdToTypeCodes();

    for (String dataCode : dataCodes) {
      String dataId = ((BaseData)dbMapClone.get(dataCode)).getDataID();
      dbMapClone.remove(dataCode);
      if (baseDataTypes.containsKey(dataCode)) {
        baseDataTypes.remove(dataCode);
        baseDataTypeIdToCodes.remove(dataId);
      }
    }

    baseDataCacheUtil.putBaseData(dbMapClone);
    baseDataCacheUtil.putBaseDataList(baseDataTypes);
    baseDataCacheUtil.putBaseDataTypeIdToTypeCodes(baseDataTypeIdToCodes);

    servletContext.setAttribute("baseDataMap", dbMapClone);
  }

  public static void updateBataDataType(BaseDataType baseDataType) throws Exception
  {
    Map dbMapClone = (Map)((HashMap)servletContext.getAttribute("baseDataMap")).clone();
    baseDataCacheUtil = (BaseDataCacheUtil)ac.getBean("com.eorchis.module.basedata.service.cache.BaseDataCacheUtil");
    baseDataCacheUtil.putBaseData(dbMapClone);
    servletContext.setAttribute("baseDataMap", dbMapClone);
    Map baseDataTypeIdToCodes = baseDataCacheUtil.getBaseDataTypeIdToTypeCodes();

    Map baseDataListMap = new HashMap();

    IBaseDataTypeService baseDataTypeService = (IBaseDataTypeService)ac.getBean("com.eorchis.module.basedata.service.impl.BaseDataTypeServiceImpl");
    IBaseDataService baseDataService = (IBaseDataService)ac.getBean("com.eorchis.module.basedata.service.impl.BaseDataServiceImpl");

    Map dbsMap = new HashMap();

    BaseDataTypeCondition baseDataTypeCondition = new BaseDataTypeCondition();
    baseDataTypeCondition.setSearchTypeID(baseDataType.getTypeID());
    BaseDataType bdt = baseDataTypeService.getBaseDataType(baseDataTypeCondition);
    if (bdt != null) {
      BaseDataCondition baseDataCondition = new BaseDataCondition();
      baseDataCondition.setSearchActiveState(BaseData.IS_ACTIVE_Y + "");
      baseDataCondition.setSearchDataTypeID(bdt.getTypeID());
      List<BaseData> baseDataLists = baseDataService.getBaseDataList(baseDataCondition);
      if ((baseDataLists == null) || ("".equals(baseDataLists)))
      {
        baseDataLists = new ArrayList();
      }
      else for (BaseData baseData : baseDataLists) {
          baseData.setBaseDataType(bdt);
          dbsMap.put(baseData.getDataCode(), baseData);
        }

      baseDataListMap.put(bdt.getTypeCode(), baseDataLists);
    }

    baseDataTypeIdToCodes.put(bdt.getTypeID(), bdt.getTypeCode());

    baseDataCacheUtil.putBaseDataList(baseDataListMap);
    baseDataCacheUtil.putBaseDataTypeIdToTypeCodes(baseDataTypeIdToCodes);
    baseDataCacheUtil.putBaseData(dbsMap);
    servletContext.setAttribute("baseDataMap", dbsMap);
  }

  public static void discardOrReuseBaseData(List<BaseData> baseDatas)
    throws Exception
  {
    Map dbMapClone = (Map)((HashMap)servletContext.getAttribute("baseDataMap")).clone();

    baseDataCacheUtil = (BaseDataCacheUtil)ac.getBean("com.eorchis.module.basedata.service.cache.BaseDataCacheUtil");

    Map baseDataTypes = baseDataCacheUtil.getBaseDataList();
    Map baseDataTypeIdToCodes = baseDataCacheUtil.getBaseDataTypeIdToTypeCodes();
    for (BaseData bd : baseDatas) {
      List bds = new ArrayList();
      if ((bd.getBaseDataType() != null) && (!"".equals(bd.getBaseDataType())))
      {
        String dataId = bd.getBaseDataType().getTypeID();
        if (baseDataTypeIdToCodes.containsKey(dataId)) {
          bds = (List)baseDataTypes.get(baseDataTypeIdToCodes.get(dataId));
          if (bd.getActiveState().intValue() == BaseData.IS_ACTIVE_Y.intValue()) {
            bds.add(bd);
            bd.getBaseDataType().setTypeCode((String)baseDataTypeIdToCodes.get(dataId));
            dbMapClone.put(bd.getDataCode(), bd);
          } else if (bd.getActiveState().intValue() == BaseData.IS_ACTIVE_N.intValue()) {
            Iterator ite = bds.iterator();
            while (ite.hasNext()) {
              BaseData baseData = (BaseData)ite.next();
              if (baseData.getDataCode().equals(bd.getDataCode()))
              {
                ite.remove();
                dbMapClone.remove(baseData.getDataCode());
              }
            }
          }
          baseDataTypes.put(baseDataTypeIdToCodes.get(dataId), bds);
          baseDataCacheUtil.putBaseDataList(baseDataTypes);
        }
      }
    }
    baseDataCacheUtil.putBaseData(dbMapClone);
    servletContext.setAttribute("baseDataMap", dbMapClone);
  }

  public void initBaseDataListMap()
    throws Exception
  {
    baseDataCacheUtil = (BaseDataCacheUtil)ac.getBean("com.eorchis.module.basedata.service.cache.BaseDataCacheUtil");

    Map baseDataListMap = new HashMap();

    Map baseDataTypeIdToCodes = new HashMap();
    this.baseDataTypeService = ((IBaseDataTypeService)ac.getBean("com.eorchis.module.basedata.service.impl.BaseDataTypeServiceImpl"));

    this.baseDataService = ((IBaseDataService)ac.getBean("com.eorchis.module.basedata.service.impl.BaseDataServiceImpl"));

    List<BaseDataType> bdts = this.baseDataTypeService.findBaseDataList(new BaseDataTypeCondition());

    Map dbsMap = new HashMap();
    BaseDataCondition baseDataCondition;
    if ((bdts != null) && (bdts.size() > 0)) {
      baseDataCondition = new BaseDataCondition();
      for (BaseDataType bdt : bdts) {
        baseDataCondition.setSearchActiveState(BaseData.IS_ACTIVE_Y + "");
        baseDataCondition.setSearchDataTypeID(bdt.getTypeID());
        List<BaseData> baseDataLists = this.baseDataService.getBaseDataList(baseDataCondition);

        if ((baseDataLists == null) || ("".equals(baseDataLists)))
        {
          baseDataLists = new ArrayList();
        }
        else for (BaseData baseData : baseDataLists) {
            baseData.setBaseDataType(bdt);
            dbsMap.put(baseData.getDataCode(), baseData);
          }

        baseDataListMap.put(bdt.getTypeCode(), baseDataLists);
        baseDataTypeIdToCodes.put(bdt.getTypeID(), bdt.getTypeCode());
      }
    }

    baseDataCacheUtil.putBaseDataList(baseDataListMap);
    baseDataCacheUtil.putBaseDataTypeIdToTypeCodes(baseDataTypeIdToCodes);
    baseDataCacheUtil.putBaseData(dbsMap);
    servletContext.setAttribute("baseDataMap", dbsMap);
  }

  public static BaseData getBaseDataType(String dataCode)
    throws Exception
  {
    baseDataCacheUtil = (BaseDataCacheUtil)ac.getBean("com.eorchis.module.basedata.service.cache.BaseDataCacheUtil");

    Map baseDatas = baseDataCacheUtil.getBaseData();

    BaseData baseData = new BaseData();
    if (baseDatas.containsKey(dataCode)) {
      baseData = (BaseData)baseDatas.get(dataCode);
    }
    return baseData;
  }
}